﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.IO;
using System.Reflection;
using BizzReports;
using log4net;

namespace BizzUI.Reports
{
    class ReportsManager
    {
        private static readonly ILog auditLog =
                    LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private static ReportsManager _instance = null;
        private List<IBizzCommand> Commands;
        private string reportsFolder;

        protected ReportsManager()
        {
            reportsFolder = ConfigurationManager.AppSettings["CustomReports"].ToString();
            Commands = new List<IBizzCommand>();
            
        }
        public static ReportsManager getInstance()
        {
            if (_instance == null)
                _instance = new ReportsManager();
            _instance.scanForReports();
            return _instance;
        }

        public void scanForReports()
        {
            string dll = "";
            try
            {
                var files = Directory.GetFiles(reportsFolder).Where(name => name.EndsWith(".dll"));
                foreach (string file in files)
                {
                    dll = file;
                    Assembly concreteInbox = Assembly.LoadFile(file);
                    //Buscar bandejas de entrada 
                    Type report = validateAssembly(concreteInbox, "showReportPanel");
                    if (report != null)
                    {
                        IBizzCommand newCommand = (IBizzCommand)Activator.CreateInstance(report);
                        //Solo cargo tipos de bandejas que no esten cargados
                        if (Commands.Find(commandType => commandType.GetType() == newCommand.GetType()) == null)
                            Commands.Add(newCommand);
                    }
                }
            }
            catch (Exception ex)
            {
                auditLog.Warn("Error al intentar cargar un nuevo reporte de la libreria: " + dll + " " + ex.Message);
            }



        }
        private Type validateAssembly(Assembly assembly, string operation)
        {
            Type ret = null;

            Type[] types = assembly.GetTypes();

            foreach (Type t in types)
            {

                var method = t.GetMethods().Where(met => met.Name.Contains(operation)).FirstOrDefault();
                if (method != null)
                    ret = t;
            }


            return ret;
        }

        public List<IBizzCommand> getBizzCommandList()
        {
            return Commands;
        }
    }
}
